/**
 * author      : dormi330
 * date        : 2018/6/26
 * project     : mybatis
 * description : 应用层服务
 */

package com.deep.trade.application.order;

import com.deep.trade.adaptor.required.member.Member;
import com.deep.trade.adaptor.required.member.MemberService;
import com.deep.trade.common.TradeException;
import com.deep.trade.domain.order.OrderQueryRepository;
import com.deep.trade.domain.order.OrderRepository;
import com.deep.trade.domain.order.TradeOrder;
import com.deep.trade.infrastructure.utils.CommonUtils;
import com.deep.trade.order.InDtoCancelOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class CancelOrderService {

    @Autowired
    private OrderRepository orderRepository;
    private static final int ONLY_ONE_SHOULD_BE_UPDATED = 1;

    @Autowired
    private OrderQueryRepository orderQueryRepository;

    @Autowired
    private MemberService memberService;

    private Logger logger = LoggerFactory.getLogger(this.getClass().getName());

    /**
     * 获取 TradeOrder 订单, 并确保存在
     *
     * @param tenantCode   租户code
     * @param tradeOrderId id
     * @return TradeOrder
     * @throws Exception
     */
    private TradeOrder assureTradeOrder(String tenantCode, String tradeOrderId) throws Exception {
        TradeOrder tradeOrder = orderQueryRepository.tradeOrderOfId(tenantCode, tradeOrderId);
        if (null == tradeOrder) {
            String errMsg = String.format("no such tradeOrder, tenantCode=%s,  tradeOrderId=%s", tenantCode, tradeOrderId);
            throw new TradeException(errMsg);
        }
        return tradeOrder;
    }

    /**
     * 取消一个订单, 无须事务控制
     *
     * @throws Exception
     */
    public void cancelTradeOrder(InDtoCancelOrder inDtoCancelOrder) throws Exception {
        logger.info("{}, tenantCode={}, inDtoCancelOrder={}", CommonUtils.currentClassAndMethod(), inDtoCancelOrder);

        // ====== public 入参检测 =======
        String tenantCode = inDtoCancelOrder.getTenantCode();
        if (null == tenantCode) throw new TradeException("tenantCode cannot be null");

        String tradeOrderId = inDtoCancelOrder.getTradeOrderId();
        if (null == tradeOrderId) throw new TradeException("tradeOrderId cannot be null");

        Member member = memberService.memberOfToken(tenantCode, inDtoCancelOrder.getToken());
        if (null == member) throw new TradeException("memberId cannot be null");

        // ====== 获取领域对象 =======
        TradeOrder tradeOrder = assureTradeOrder(tenantCode, tradeOrderId);
        if (!member.getId().equals(tradeOrder.getMemberId())) {
            throw new TradeException("the order's memberId doesn't match");
        }

        // ====== 领域对象操作 =======
        tradeOrder.cancel();

        // ====== 存储 =======
        if (ONLY_ONE_SHOULD_BE_UPDATED != orderRepository.updateTradeOrderStatus(tradeOrder)) {
            throw new TradeException("audit fail, cannot get order to audit");
        }
    }
}
